home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / xnsecho / xnsecho.c < prev   
C/C++ Source or Header  |  1989-12-17  |  3KB  |  134 lines

  1. /*
  2.  * This is an example of an XNS echo client.
  3.  * It uses the protocol defined in the Xerox manual "Internet Transport
  4.  * Protocols" (XNSS 028112, Dec. 1981), Chapter 6, pp. 37-38.
  5.  * Notice that on 4.3BSD systems, the kernel handles these requests,
  6.  * if a server isn't listening on the echo port.
  7.  */
  8.  
  9. #include    <stdio.h>
  10. #include    <sys/types.h>
  11. #include    <sys/socket.h>
  12. #include    <netns/ns.h>
  13. #include    <netns/idp.h>
  14.  
  15. #define    ECHO_SERV_ADDR    "123:02.07.01.00.6d.82:2"
  16.                 /* <netid>:<hostid>:<port> */
  17.                 /* the <port> of 2 is the well-known port
  18.                    (XNS "socket") for an XNS echo server */
  19.  
  20. #define    ECHO_REQUEST    1    /* client sends a request as operation field */
  21. #define    ECHO_REPLY    2    /* server responds with this as op field */
  22. #define    OP_SIZE        sizeof(short)
  23.             /* size of the operation field at front of packet */
  24.  
  25. #define    MAXLINE        255
  26.  
  27. extern int    rtt_d_flag;    /* defined in the rtt.h header file */
  28.                 /* to print the RTT timing info */
  29. char    *pname;
  30.  
  31. main(argc, argv)
  32. int    argc;
  33. char    *argv[];
  34. {
  35.     FILE            *fp, *fopen();
  36.     register int        i, sock;
  37.     struct idp        idp_hdr;
  38.  
  39.     pname = argv[0];
  40.     --argc; ++argv;
  41.  
  42.     rtt_d_flag = 1;        /* to print the RTT timing info */
  43.  
  44.     /*
  45.      * Create an IDP socket, bind any local address and record the
  46.      * server's address.
  47.      */
  48.  
  49.     if ( (sock = idp_open(ECHO_SERV_ADDR, (char *) 0, 0)) < 0)
  50.         err_sys("can't create IDP socket");
  51.  
  52.     /*
  53.      * Set the socket option for default headers on output.
  54.      * We set the packet type field of the IDP header to NSPROTO_ECHO.
  55.      * Note that all the system uses from this structure is the packet
  56.      * type field (idp_pt), and this will be the packet type on all
  57.      * datagrams sent on this socket.
  58.      * Note that the packet type field is a single byte, so there are
  59.      * no byte-ordering problems.
  60.      */
  61.  
  62.     idp_hdr.idp_pt = NSPROTO_ECHO;        /* packet type */
  63.     if (setsockopt(sock, 0, SO_DEFAULT_HEADERS,
  64.             (char *) &idp_hdr, sizeof(idp_hdr)) < 0)
  65.         err_sys("setsockopt error");
  66.  
  67.     /*
  68.      * Main loop.
  69.      * For every command line argument (or stdin) call doit();
  70.      */
  71.  
  72.     i = 0;
  73.     fp = stdin;
  74.     do {
  75.         if (argc > 0 && (fp = fopen(argv[i], "r")) == NULL) {
  76.             fprintf(stderr, "%s: can't open %s\n", pname, argv[i]);
  77.             continue;
  78.         }
  79.  
  80.         doit(sock, fp);
  81.  
  82.     } while (++i < argc);
  83.  
  84.     close(sock);
  85.     exit(0);
  86. }
  87.  
  88. /*
  89.  * Read the contents of the FILE *fp, write each line to the
  90.  * socket (to the server process), then read a line back from
  91.  * the socket and print it on the standard output.
  92.  */
  93.  
  94. doit(sock, fp)
  95. register int    sock;
  96. register FILE    *fp;
  97. {
  98.     int    n, sendlen;
  99.     char    *fgets();
  100.     char    sendline[MAXLINE], recvline[MAXLINE];
  101.  
  102.     while (fgets(sendline + OP_SIZE, MAXLINE, fp) != NULL) {
  103.         /*
  104.          * Set the first 2 bytes of the packet to ECHO_REQUEST.
  105.          */
  106.  
  107.         *( u_short * ) sendline = htons(ECHO_REQUEST);
  108.                         /* op = echo request */
  109.         sendlen = strlen(sendline + OP_SIZE) + OP_SIZE;
  110.  
  111.         if ( (n = dgsendrecv(sock, sendline, sendlen, recvline, MAXLINE,
  112.                 (struct sockaddr *) 0, 0)) < 0)
  113.             err_sys("drsendrecv error");
  114.  
  115.         /*
  116.          * There had better be at least 2 bytes in the datagram, and
  117.          * the first 2 bytes must be ECHO_REPLY.
  118.          */
  119.  
  120.         if (n < OP_SIZE)
  121.             err_dump("invalid length");
  122.         if ( (*(u_short *) recvline) != htons(ECHO_REPLY))
  123.             err_dump("unexpected operation field");
  124.  
  125.         recvline[n] = 0;    /* null terminate */
  126.         fputs(recvline + OP_SIZE, stdout);
  127.     }
  128.  
  129.     if (ferror(fp))
  130.         err_sys("error reading file");
  131.  
  132.     fclose(fp);    /* close the FILE, leave the socket open */
  133. }
  134.